/*
 * Copyright (c) 2010 Mathias Garbe <code@mathias-garbe.de>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef GAMEINFO_HPP
#define GAMEINFO_HPP

#include <string>
#include "client.hpp"
#include <QSettings>
#include <QApplication>

class GameInfo
{
private:
    Games::GameType game;
    std::string reg32, reg64;

public:
    GameInfo(Games::GameType game, std::string reg32, std::string reg64);
    GameInfo()
    {
        this->game = Games::NOGAME;
        this->reg32 = "";
        this->reg64 = "";
    }

    virtual std::string getExe();

    virtual std::string getArgs()
    {
        if(this->game == Games::TD || this->game == Games::RA)
        {
            return "-LAN -cd.";
        }
        else
        {
            return "";
        }
    }

    virtual std::string getPath();

    virtual Games::GameType getType();
};

namespace StaticGameInfo
{
    static GameInfo getGameInfo(int gameID)
    {
        static GameInfo games[5];
        static bool init = false;

        if(!init)
        {
            init = true;

            games[0] = GameInfo(Games::TD, "Software\\Westwood\\Command & Conquer Windows 95 Edition", 
                "Software\\Wow6432Node\\Westwood\\Command & Conquer Windows 95 Edition");

            games[1] = GameInfo(Games::RA, "Software\\Westwood\\Red Alert Windows 95 Edition", 
                "Software\\Wow6432Node\\Westwood\\Red Alert Windows 95 Edition");

            games[2] = GameInfo(Games::TS, "Software\\Westwood\\Tiberian Sun", 
                "Software\\Wow6432Node\\Westwood\\Tiberian Sun");

            games[3] = GameInfo(Games::RA2, "Software\\Westwood\\Red Alert 2", 
                "Software\\Wow6432Node\\Westwood\\Red Alert 2");

            games[4] = GameInfo(Games::RA2YR, "Software\\Westwood\\Yuri's Revenge", 
                "Software\\Wow6432Node\\Westwood\\Yuri's Revenge");
        }

        if(gameID < 0)
            gameID = 0;

        if(gameID > 4)
            gameID = 4;

        return games[gameID];
    }
}

class AdvancedGameInfo : public GameInfo
{
private:
    Games::GameType game;
    std::string exe, args, description;
    bool readOnly;

public:
    AdvancedGameInfo(Games::GameType game, std::string exe = "", std::string args = "", std::string description = "", bool readOnly = false)
        : GameInfo()
    {
        this->game = game;
        this->exe = exe;
        this->args = args;
        this->description = description;
        this->readOnly = readOnly;
    }

    std::string getExe()
    {
        return exe;
    }

    std::string getArgs()
    {
        return args;
    }

    std::string getDescription()
    {
        return description;
    }

    std::string getPath()
    {
        std::string gameExe = this->getExe();
        if(gameExe.find_last_of("\\") != std::string::npos)
        {
            return gameExe.substr(0, gameExe.find_last_of("\\") + 1);
        }
        return "";
    }

    Games::GameType getType()
    {
        return game;
    }

    bool isReadOnly()
    {
        return this->readOnly;
    }


    // Static method to load/save vectors of game infos to QSettings
    static void saveGameInfos(int game, std::vector<AdvancedGameInfo> gameInfos)
    {
        QSettings settings;

        int i=0;
        for (std::vector<AdvancedGameInfo>::iterator it = gameInfos.begin(); it!=gameInfos.end(); ++it) 
        {
            AdvancedGameInfo tmpGameInfo = (*it);

            if(!tmpGameInfo.isReadOnly())
            {
                std::stringstream tmpPre;
                tmpPre << "CustomPath_Advanced_" << Games::getGameString(game) << "_" << i << "/";

                std::stringstream tmpFull;

                tmpFull << tmpPre.str() << "exe";
                settings.setValue(tmpFull.str().c_str(), tmpGameInfo.getExe().c_str());
                tmpFull.str("");

                tmpFull << tmpPre.str() << "args";
                settings.setValue(tmpFull.str().c_str(), tmpGameInfo.getArgs().c_str());
                tmpFull.str("");

                tmpFull << tmpPre.str() << "description";
                settings.setValue(tmpFull.str().c_str(), tmpGameInfo.getDescription().c_str());
                tmpFull.str("");

                i++;
            }
        }

        std::stringstream tmpCount;
        tmpCount << "CustomPath_Advanced_" << Games::getGameString(game) << "/Count";

        settings.setValue(tmpCount.str().c_str(), i);

    }

    static std::vector<AdvancedGameInfo> loadGameInfos(int game, bool advancedOnly = false)
    {
        QSettings settings;
        std::vector<AdvancedGameInfo> gameInfo;

        if(!advancedOnly)
        {
            // Check for registry stuff
            GameInfo tmpGameInfo = StaticGameInfo::getGameInfo(game);

            if(tmpGameInfo.getExe() != "")
            {
                gameInfo.push_back(AdvancedGameInfo((Games::GameType)game, tmpGameInfo.getExe(), tmpGameInfo.getArgs(), "(imported)", true));
            }

            // Check for simple game
            /*std::stringstream tmp;
            tmp << "CustomPath/" << Games::getGameString(game);
            std::string simpleGame = settings.value(tmp.str().c_str(), "").toString().toStdString();

            if(simpleGame != "")
            {
                gameInfo.push_back(AdvancedGameInfo((Games::GameType)game, simpleGame, "", "(by simple dialog)", true));
            }*/
        }


        std::stringstream tmpCount;
        tmpCount << "CustomPath_Advanced_" << Games::getGameString(game) << "/Count";
        int count = settings.value(tmpCount.str().c_str(), 0).toInt();
        for(int i=0; i<count; i++)
        {
            std::stringstream tmpPre;
            tmpPre << "CustomPath_Advanced_" << Games::getGameString(game) << "_" << i << "/";

            std::stringstream tmpFull;

            tmpFull << tmpPre.str() << "exe";
            std::string exe = settings.value(tmpFull.str().c_str(), "").toString().toStdString();
            tmpFull.str("");

            tmpFull << tmpPre.str() << "args";
            std::string args = settings.value(tmpFull.str().c_str(), "").toString().toStdString();
            tmpFull.str("");

            tmpFull << tmpPre.str() << "description";
            std::string description = settings.value(tmpFull.str().c_str(), "").toString().toStdString();
            tmpFull.str("");

            gameInfo.push_back(AdvancedGameInfo((Games::GameType)game, exe, args, description));
        }

        return gameInfo;
    }
};


#endif
